<?php
/**
 * 注册成功后发送短信或邮箱提醒
 */
include_once 'Email.class.php';
include_once 'SmsMail.class.php';
include_once 'myMailOne.class.php'; //接口
class Register {

    private $_mailObj;

    //通过依赖注入获取类的实例
    public function __construct(myMailOne $mailObj) {
        $this->_mailObj = $mailObj;
        //var_dump($this->_mailObj);
    }

    //通过php反射获取创建类的实例
    /* public function getMailObj($mailName) {
        try
        {
            $class = new ReflectionClass($mailName);
            $this->_mailObj = $class->newInstance();
            var_dump($this->_mailObj);
        }
        catch(ReflectionException $e)
        {
            $this->_mailObj = "";
        }
    } */

    /*
     * 注册
     */
    public function doRegister() {
        //1、这里是如何注册
        //Todo
        //2、发送信息
        $this->_mailObj->send();
    }
}

/* 此处省略若干行 */
$reg = new Register(new SmsMail()); //使用短信发送  传入短信类的实例
$reg->doRegister();

$reg = new Register(new Email()); //使用邮箱发送  传入邮箱类的实例
$reg->doRegister();

//通过php反射获取创建类的实例
/* $res = new Register();
$res->getMailObj('SmsMail');
$res->doRegister(); */

//产生了耦合 实现了解耦
//依赖反转准则
/*说这个话题之前先讲一个比较高端的思想--'依赖倒置原则' "依赖倒置是一种软件设计思想，在传统软件中，上层代码依赖于下层代码，当下层代码有所改动时，上层代码也要相应进行改动，
因此维护成本较高。而依赖倒置原则的思想是，上层不应该依赖下层，应依赖接口。意为上层代码定义接口，下层代码实现该接口，
从而使得下层依赖于上层接口，降低耦合度，提高系统弹性"*/

//代码复用性很低，高层过度依赖于底层。那么我们就考虑'依赖倒置原则'，让底层继承高层制定的接口，高层依赖于接口。
//上例就使用了"注入"这个思想，就像注射器一样将一个类的实例注入到另一个类的实例中去，需要用什么就注入什么
//"注入"不仅可以通过构造函数注入，也可以通过属性注入，上面你可以可以通过一个"setter"来动态为"mailObj"这个属性赋值。



//致是这样，所有的服务，不管是数据库，还是缓存，用一个容器，形象点说就是一个变量ioc存着。用的时候ioc->db ioc->cache来取，这样当用到db或cahce时到处new了

//场景就是当你需要调用别的对象方法而又不想程序的耦合度太高的时候。参数要求对象必须为C类的实例，这里的C是php的类型约束

